#
# LuckyBot4, a python IRC bot
# (c) Copyright 2008 by Lucas van Dijk
# http://www.return1.net
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
#
# $Id: config.py 47 2009-03-24 15:49:10Z luckyluke56 $
#

try:
	import pygtk
	pygtk.require('2.4')
except:
	pass

try:
	import gtk
	import gobject
	import gtk.glade
except:
	raise

from luckybot.views.gui import dialogs
from gettext import gettext as _
import luckybot.path
import base64

class ConfigWindow(object):
	"""
		Represents the config window
	"""

	def __init__(self, bot):
		self.bot = bot

		self.xml = gtk.glade.XML(luckybot.path.get_base_path('data', 'glade', 'config.glade'), 'configDialog', 'luckybot')
		self.window = self.xml.get_widget('configDialog')

		self.window.set_title(_("Lucky Bot - Preferences"))

		self.xml.signal_autoconnect(self)
		self.window.connect('destroy', self.on_quit)

		self.load_config()

	def run(self):
		"""
			Runs the dialog
		"""

		return self.window.run()

	def load_config(self):
		"""
			Fills all setting in to their places
		"""

		# General tab
		self.xml.get_widget('txtCmdPrefix').set_text(self.bot.settings.get('Bot', 'command_prefix'))

		# Load languages
		languages = []

		for plugin in self.bot.plugins.plugins.itervalues():
			plugin_langs = plugin.lang.languages_available

			for lang in plugin_langs:
				if lang in languages:
					continue

				languages.append(lang)

		languages.sort()

		# Setup combobox
		model = gtk.ListStore(str)
		combo = self.xml.get_widget('cmbLanguage')
		combo.set_model(model)

		i = 0
		index = 0
		for language in languages:
			model.append([str(language).title()])

			if language.lower() == self.bot.settings.get('Bot', 'language').lower():
				index = i

			i += 1

		renderer = gtk.CellRendererText()
		combo.pack_start(renderer)
		combo.add_attribute(renderer, 'text', 0)

		combo.set_active(index)

		# Load servers
		self.load_servers()

		# Load admins
		self.load_admins()

		# Load plugins
		self.load_plugins()

	def load_servers(self):
		"""
			Loads all bot admins and puts them in a listview
		"""

		servers = self.bot.get_servers()

		# Setup treeview
		tree = self.xml.get_widget('treeServers')

		model = gtk.ListStore(str, str, str, str, str)
		tree.set_model(model)

		headings = ['Hostname', 'Port', 'Channels', 'Nickname']
		i = 0

		self.server_columns = []

		while i < 4:
			column = gtk.TreeViewColumn(headings[i])
			renderer = gtk.CellRendererText()
			renderer.set_property('editable', True)
			renderer.connect('edited', self.on_cell_editted, (model, i))
			column.pack_start(renderer)
			column.set_attributes(renderer, text = i, editable = i)

			tree.append_column(column)
			self.server_columns.append(column)

			i += 1

		column = gtk.TreeViewColumn('Password')
		renderer = gtk.CellRendererText()
		renderer.set_property('editable', True)
		renderer.connect('edited', self.on_cell_editted, (model, 4))
		column.pack_start(renderer)
		column.set_attributes(renderer, text = 4, editable = 4)

		self.server_columns.append(column)

		# Add admins from settings to treeview
		for server in servers:
			if not 'port' in server:
				server['port'] = '6667'

			if not 'channels' in server:
				server['channels'] = ''

			if not 'password' in server:
				server['password'] = ''

			model.append([server['hostname'], server['port'], server['channels'], server['nickname'], server['password']])

	def on_cell_editted(self, cell, path, new_text, userdata):
		"""
			Called when editting of a cell finishes
		"""

		model, column = userdata
		model[path][column] = new_text

	def on_checkPasswords_toggled(self, checkbox):
		"""
			Called when the 'Show nickserv passwords' checkbox is toggled
		"""

		tree = self.xml.get_widget('treeServers')

		if checkbox.get_active():
			tree.append_column(self.server_columns[4])
		else:
			tree.remove_column(self.server_columns[4])

	def on_btnServerAdd_clicked(self, button):
		"""
			Called when the user clicks 'Add Server'
		"""

		# Add a new model entry
		tree = self.xml.get_widget('treeServers')
		model = tree.get_model()

		iter = model.append(['irc.hostname.com', '6667', '', '', ''])
		path = model.get_path(iter)

		tree.set_cursor(model.get_path(iter), self.server_columns[0], True)

	def on_btnServerDelete_clicked(self, button):
		"""
			Called when the user clicks 'Delete Server'
		"""

		model, iter = self.xml.get_widget('treeServers').get_selection().get_selected()

		if iter == None:
			return

		# display confirmation dialog
		dialog = gtk.MessageDialog(self.window, type=gtk.MESSAGE_WARNING,
			buttons=gtk.BUTTONS_YES_NO, message_format=
				_("Are you sure you want to delete this server?"))

		response = dialog.run()
		dialog.hide()

		if response == gtk.RESPONSE_YES:
			model.remove(iter)


	def load_admins(self):
		"""
			Loads all bot admins and puts them in a listview
		"""

		# Setup treeview
		tree = self.xml.get_widget('treeUsers')

		model = gtk.ListStore(str)
		tree.set_model(model)

		column = gtk.TreeViewColumn('Username')
		renderer = gtk.CellRendererText()
		column.pack_start(renderer)
		column.set_attributes(renderer, text = 0)

		tree.append_column(column)

		# Add admins from settings to treeview
		admins = self.bot.settings.options('Admins')
		for admin in admins:
			model.append([admin.title()])

	def on_btnUserAdd_clicked(self, button):
		"""
			Called when the user clicks Add admin button
		"""

		# Open dialog
		dialog = dialogs.AddUserDialog(self.window)
		response = dialog.run()

		if response == gtk.RESPONSE_OK:
			username = dialog.txtNickname.get_text()
			password = dialog.txtPassword.get_text()

			if not (username and password):
				message = gtk.MessageDialog(self.window, type=gtk.MESSAGE_ERROR,
					buttons=gtk.BUTTONS_OK, message_format=
					_("No username or password given"))
				message.run()
				message.hide()
				return

			if self.bot.settings.has_option('Admins', username.lower()):
				message = gtk.MessageDialog(self.window, type=gtk.MESSAGE_ERROR,
					buttons=gtk.BUTTONS_OK, message_format=
					_("Username already exists"))
				message.run()
				message.hide()
				return

			self.bot.settings.set('Admins', username, base64.b64encode(password))
			tree = self.xml.get_widget('treeUsers')
			tree.get_model().append([username])

		dialog.hide()

	def on_btnUserEdit_clicked(self, button):
		"""
			Called when the user wants to edit an user
		"""

		# Get current selected
		selection = self.xml.get_widget('treeUsers').get_selection()

		model, iter = selection.get_selected()

		if iter == None:
			return

		# Open dialog and fill textboxes
		dialog = dialogs.AddUserDialog(self.window)
		dialog.txtNickname.set_text(model[iter])
		dialog.txtPassword.set_text(base64.b64decode(self.bot.settings.get('Admins', model[iter])))

		dialog.run()
		dialog.hide()

	def load_plugins(self):
		"""
			Adds all plugins to the treeview
		"""

		# Setup treeview
		tree = self.xml.get_widget('treePlugins')

		model = gtk.ListStore(bool, str, str, str, str, str)
		tree.set_model(model)

		column = gtk.TreeViewColumn(_('Enabled'))
		renderer = gtk.CellRendererToggle()
		column.pack_start(renderer)
		renderer.connect('toggled', self.on_plugin_toggled, (model, 0))
		column.set_attributes(renderer, active = 0)

		tree.append_column(column)

		column = gtk.TreeViewColumn(_('Name'))
		renderer = gtk.CellRendererText()
		column.pack_start(renderer)
		column.set_attributes(renderer, text = 2)

		tree.append_column(column)

		column = gtk.TreeViewColumn(_('Version'))
		renderer = gtk.CellRendererText()
		column.pack_start(renderer)
		column.set_attributes(renderer, text = 3)

		tree.append_column(column)

		column = gtk.TreeViewColumn(_('Description'))
		renderer = gtk.CellRendererText()
		column.pack_start(renderer)
		column.set_attributes(renderer, text = 4)

		tree.append_column(column)

		for dir, plugin in self.bot.plugins.available_plugins:
			if plugin in self.bot.plugins.plugins:
				# Loaded plugin
				self.add_plugin(dir, True, self.bot.plugins.plugins[plugin].PLUGIN_INFO)
			else:
				# Not loaded
				# Get the plugin class
				try:
					plugin_obj = self.bot.plugins.get_plugin_class(dir, plugin)
				except:
					continue

				plugin_obj.PLUGIN_INFO['dirname'] = plugin
				self.add_plugin(dir, False, plugin_obj.PLUGIN_INFO)
				del plugin_obj


	def add_plugin(self, dir, active, plugin_info):
		"""
			Adds a plugin to the tree view
		"""

		tree = self.xml.get_widget('treePlugins')
		model = tree.get_model()

		column_spec = [
			active,
			plugin_info['dirname'],
			plugin_info['name'] if 'name' in plugin_info else '',
			plugin_info['version'] if 'version' in plugin_info else '',
			plugin_info['description'] if 'description' in plugin_info else '',
			dir
		]

		model.append(column_spec)

	def on_plugin_toggled(self, renderer, path, user_data):
		"""
			Called when the user toggles a plugin
		"""

		model, column_index = user_data

		if not renderer.get_active():
			# Load a plugin
			if self.bot.plugins.load_plugin(model[path][5], model[path][1]):
				model[path][0] = True

				if self.bot.settings.has_option('Disabled', model[path][1]):
					self.bot.settings.remove_option('Disabled', model[path][1])
		else:
			# Unload a plugin
			self.bot.plugins.unload_plugin(model[path][1])
			model[path][0] = False

			self.bot.settings.set('Disabled', model[path][1], 'true')

	def on_quit(self, widget = None, event = None):
		"""
			Quits this window
		"""

		self.window.hide()
